`include "IF_AHB_paras.vh"
module itcm_sram #(
  parameter DP = 512,
  parameter DW = 32,
  parameter MW = 4,
  parameter AW = 32 
)(
  input             clk, 
  input  [DW-1  :0] din, 
  input  [AW-1  :0] addr,
  input             cs,
  input             we,
  input  [MW-1:0]   wem,
  output [DW-1:0]   dout
);

    reg [DW-1:0] mem_r [0:DP-1];
    reg [AW-1:0] addr_r;
    wire [MW-1:0] wen;
    wire ren;

    assign ren = cs & (~we);
    assign wen = ({MW{cs & we}} & wem);

    integer init_i;
    initial begin
        mem_r[0][31:0] = 32'b00000000000000000000000100000001;
        mem_r[0][63:32] = 32'b00000000000000000010000110000001;
        mem_r[1][31:0] = 32'b00000000001100010010000000100011;
        mem_r[1][63:32] = 32'b00000000000000011100000110000001;
        mem_r[2][31:0] = 32'b00000000001100010010001000100011;
        mem_r[2][63:32] = 32'b00000000000001011010000110000001;
        mem_r[3][31:0] = 32'b00000000001100010010010000100011;
        mem_r[3][63:32] = 32'b00000000000000010101000110000001;
        mem_r[4][31:0] = 32'b00000000001100010010011000100011;
        mem_r[4][63:32] = 32'b00000000000000000100000110000001;
        mem_r[5][31:0] = 32'b00000000001100010010100000100011;
        mem_r[5][63:32] = 32'b00000000000000001011000110000001;
        mem_r[6][31:0] = 32'b00000000001100010010101000100011;
        mem_r[6][63:32] = 32'b00000000000010111110000110000001;
        mem_r[7][31:0] = 32'b00000000001100010010110000100011;
        mem_r[7][63:32] = 32'b00000000000000010101000110000001;
        mem_r[8][31:0] = 32'b00000000001100010010111000100011;
        mem_r[8][63:32] = 32'b00000000000000010100000110000001;
        mem_r[9][31:0] = 32'b00000010001100010010000000100011;
        mem_r[9][63:32] = 32'b00000000000000101100000110000001;
        mem_r[10][31:0] = 32'b00000010001100010010001000100011;
        mem_r[10][63:32] = 32'b00000000000000001010000010000001;
        mem_r[11][31:0] = 32'b00000000000000000000001000000001;
        mem_r[11][63:32] = 32'b11111111111100001000001010010011;
        mem_r[12][31:0] = 32'b00000010010100100101000001100011;
        mem_r[12][63:32] = 32'b00000000000100100000001100010011;
        mem_r[13][31:0] = 32'b00000000000100110101110101100011;
        mem_r[13][63:32] = 32'b00000000010000010000010000110011;
        mem_r[14][31:0] = 32'b00000000000001000010010100000011;
        mem_r[14][63:32] = 32'b00000000011000010000010010110011;
        mem_r[15][31:0] = 32'b00000000000001001010010110000011;
        mem_r[15][63:32] = 32'b00000000101101010101011101100011;
        mem_r[16][31:0] = 32'b00000000000001010000011110010011;
        mem_r[16][63:32] = 32'b00000110111100010010001000100011;
        mem_r[17][31:0] = 32'b00000000000001011000010100010011;
        mem_r[17][63:32] = 32'b00000000100001010010000000100011;
        mem_r[18][31:0] = 32'b00000000000001111000010110010011;
        mem_r[18][63:32] = 32'b00000000100101011010000000100011;
        mem_r[19][31:0] = 32'b00000000000100110000001100010011;
        mem_r[19][63:32] = 32'b00000000000100100000001000010011;
        mem_r[20][31:0] = 32'b00000000000000000000000000110011;
        mem_r[20][63:32] = 32'b00000000000000000000000000110011;
        for(init_i = 21; init_i < DP; init_i = init_i + 1) begin
            mem_r[init_i][31:0] = `INSTR_NOP;
            mem_r[init_i][DW-1:32] = `INSTR_NOP;
        end
    end

    genvar i;

    always @(posedge clk)
    begin
        if (ren) begin
            addr_r <= addr;
        end
    end

    generate
      for (i = 0; i < MW; i = i+1) begin :mem
        if((8*i+8) > DW ) begin: last
          always @(posedge clk) begin
            if (wen[i]) begin
               mem_r[addr][DW-1:8*i] <= din[DW-1:8*i];
            end
          end
        end
        else begin: non_last
          always @(posedge clk) begin
            if (wen[i]) begin
               mem_r[addr][8*i+7:8*i] <= din[8*i+7:8*i];
            end
          end
        end
      end
    endgenerate

  wire [DW-1:0] dout_pre;
  assign dout_pre = mem_r[addr_r];

  generate
     assign dout = dout_pre;
  endgenerate

 
endmodule